package com.lahuan.demo.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lahuan.demo.entity.Order;
import com.lahuan.demo.service.OrderService;
import com.lahuan.demo.mapper.OrderMapper;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.Date;
import java.util.Random;

/**
* <p>
* 订单服务实现类
* </p>
* @author lahuan
* @since 2021-12-15
*/
@RequiredArgsConstructor
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    //待付款:wait 已付款:pay 已完成:finish 已取消:cancel 已无效:invalid
    private final String[] statusArray = {"wait", "pay", "finish", "cancel", "invalid"};
    /**
     * 一天
     */
    long day = 1000 * 60 * 60 * 24;
    /**
     * 时间戳 2020-01-01 00:00:00
     */
    long timeStart = 1577808000000L;

    @Transactional(rollbackFor = Exception.class)
    @Override
    @ShardingTransactionType(TransactionType.XA)
    public void xaSuccess() {
        Order o3 = buildSingleData(3);
        o3.setId(3L);
        o3.setUserId(1L);
        //会分配在1号库3号表
        save(o3);

        Order o4 = buildSingleData(4);
        o4.setId(4L);
        o4.setUserId(1L);
        //会分配在1号库4号表
        save(o4);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    @ShardingTransactionType(TransactionType.XA)
    public void xaError() {
        Order o1 = buildSingleData(1);
        o1.setId(1L);
        o1.setUserId(1L);
        //会分配在1号库1号表
        save(o1);

        Order o2 = buildSingleData(2);
        o2.setId(2L);
        o2.setUserId(1L);
        String out = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        out = out + out+ out+ out+ out;
        //模拟超出数据库大小限制的异常
        o2.setOrderSn(out);
        //会分配在1号库2号表
        save(o2);
    }
    private Order buildSingleData(int i) {
        Random rd = new Random();
        Order order = new Order();
        //主键是分库条件，所以需要再这里指定主键
        order.setId((long) i);
        order.setOrderSn("no_" + i);
        //金额 1-999
        order.setTotalAmount(new BigDecimal(rd.nextInt(999) + 1));
        //随机状态
        order.setOrderStatus(statusArray[rd.nextInt(statusArray.length)]);
        order.setIsPay(rd.nextInt(2));
        //2020-01-01 为起点，1年内的随机一天
        order.setPayTime(new Date(timeStart + (rd.nextInt(365) * day)));
        order.setUserId((long) (rd.nextInt(1024)));
        return order;
    }
    /**
     * 获取QueryWrapper对象
     * @return QueryWrapper对象
     */
    @Override
    public QueryWrapper<Order> getQueryWrapper(){
        return Wrappers.<Order>query();
    }

    /**
     * 获取Lambda形式的Wrapper对象
     * @return Lambda形式的Wrapper对象
     */
    @Override
    public  LambdaQueryWrapper<Order> getLambdaWrapper(){
    return  Wrappers.<Order>lambdaQuery();
    }

}
